#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <signal.h>
#include <sys/epoll.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <stddef.h>
#include <linux/types.h>

// struct i2c_rdwr_ioctl_data {
//   struct i2c_msg *msgs;  /* ptr to array of simple messages */
//   int nmsgs;             /* number of messages to exchange */
// };

#define EPRROM_ADDR 0x50

/**
 *  i2capp w "1234"
 *  i2capp r
*/
int main(int argc,char **argv)
{ 
    int fd = 0;
    int addr = 0x50;  // 设备地址
    char mem_reg = 0x0; // mem基地址
    int ret = 0;
    unsigned char i2c_read_buf[32];
    char *str = argv[2];
    unsigned char i2c_write_buf[2];

    struct i2c_rdwr_ioctl_data i2c_ioctl_data;
    struct i2c_msg i2c_msg_write;
    struct i2c_msg i2c_msg_read[2];

    fd = open("/dev/i2c-0", O_RDWR);
    if (fd < 0) {
        printf("open failed errno=%d\n", errno);
        printf("%s\n", strerror(errno)); 
        return -1;
    }

    // 设置非UU的i2c设备地址
    if (ioctl(fd, I2C_SLAVE, addr) < 0) {
        printf("I2C_SLAVE failed\n");
        exit(1);
    }
    // 设置UU的i2c设备地址
    //ioctl(fd, I2C_SLAVE_FORCE, addr);

    ioctl(fd, I2C_TIMEOUT, 2);//超时时间
    ioctl(fd, I2C_RETRIES, 1);//重复次数

    if (argv[1][0] == 'w') {
        // 参考kernel: Documentation/i2c/dev-interface
        while (*str) {
            // 一个msgs, 代表一个start信号和停止信号
            i2c_ioctl_data.nmsgs = 1;
            i2c_ioctl_data.msgs = &i2c_msg_write;

            // 当前msgs的buf
            i2c_write_buf[0] = mem_reg;
            i2c_write_buf[1] = *str;

            i2c_ioctl_data.msgs->addr = EPRROM_ADDR;
            i2c_ioctl_data.msgs->flags = 0;
            i2c_ioctl_data.msgs->buf = i2c_write_buf;
            i2c_ioctl_data.msgs->len = 2;

            ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_ioctl_data);
            if (ret < 0) {
                perror("Failed to perform I2C transaction");
                exit(1);
            }

            // 等待10ms
            usleep(20000);
            str++;
            mem_reg++;
        }

        i2c_write_buf[0] = mem_reg;
        i2c_write_buf[1] = '\0';

        i2c_ioctl_data.nmsgs = 1;
        i2c_ioctl_data.msgs = &i2c_msg_write;
        
        i2c_ioctl_data.msgs->addr = EPRROM_ADDR;
        i2c_ioctl_data.msgs->flags = 0;
        i2c_ioctl_data.msgs->buf = i2c_write_buf;
        i2c_ioctl_data.msgs->len = 2;

        ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_ioctl_data);
        if (ret < 0) {
            perror("Failed to perform I2C transaction");
            exit(1);
        }
        // 等待10ms
        usleep(20000);
    } else if (argv[1][0] == 'r') {
        // 两个msgs, 一个w,一个r
        i2c_ioctl_data.nmsgs = 2;
        i2c_ioctl_data.msgs = i2c_msg_read;

        // i2c w
        i2c_write_buf[0] = 0x0; // 0x0地址
        
        i2c_ioctl_data.msgs[0].addr = EPRROM_ADDR;
        i2c_ioctl_data.msgs[0].flags = 0;
        i2c_ioctl_data.msgs[0].buf = i2c_write_buf;
        i2c_ioctl_data.msgs[0].len = 1;             // 控制w的长度

        // i2c r
        i2c_ioctl_data.msgs[1].addr = EPRROM_ADDR;
        i2c_ioctl_data.msgs[1].flags = I2C_M_RD;
        i2c_ioctl_data.msgs[1].buf = i2c_read_buf;
        i2c_ioctl_data.msgs[1].len = 32;           // 控制r的长度

        ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_ioctl_data);
        if (ret < 0) {
            perror("Failed to perform I2C transaction");
            exit(1);
        }

        printf("Get Data: %s\n", i2c_read_buf);
    }

    close(fd);

    return 0;
}